package com.kate.mall.order.controller;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;

//import org.apache.shiro.authz.annotation.RequiresPermissions;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.kate.mall.common.annotation.LoginUser;
import com.kate.mall.common.utils.CloneDirection;
import com.kate.mall.order.controller.form.CalculateCouponeDiscountPriceVO;
import com.kate.mall.order.controller.form.CalculateGrouponDiscountPriceVO;
import com.kate.mall.order.controller.form.CouponVO;
import com.kate.mall.order.controller.form.OrderVO;
import com.kate.mall.order.dto.GrouponRulesDTO;
import com.kate.mall.order.dto.OrderDTO;
import com.kate.mall.order.service.WxOrderService;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
import com.kate.mall.order.entity.OrderEntity;
import com.kate.mall.order.service.OrderService;
import com.kate.mall.common.utils.PageUtils;
import com.kate.mall.common.utils.R;
import io.swagger.annotations.Api;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 订单表
 *
 * @author kate-chan
 * @email 857782993@qq.com
 * @date 2022-12-16 10:48:44
 */
@Api(tags = "OrderController", description = "订单表服务")
@RestController
@RequestMapping("order/order")
@Slf4j
public class OrderController {
    @Autowired
    private OrderService orderService;

    @Resource
    private WxOrderService wxOrderService;

    /**
     * 列表
     */
    @GetMapping("/list")
    //@RequiresPermissions("order:order:list")
    @ApiOperation("获取所有订单表信息")
    public R list(@RequestParam(required = false) Map<String, Object> params){
        PageUtils page = orderService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @GetMapping("/info/{id}")
    //@RequiresPermissions("order:order:info")
    @ApiOperation("获取指定id的订单表详情")
    public R info(@PathVariable("id") Integer id){
		OrderEntity order = orderService.getById(id);

        return R.ok().put("order", order);
    }

    /**
     * 保存
     */
    @PostMapping("/save")
    @ApiOperation("添加订单表信息")
    //@RequiresPermissions("order:order:save")
    public R save(@LoginUser  Integer userId, @RequestBody OrderVO orderVo) {
        //假数据
//        userId = 4;
        try {
            Optional<OrderDTO> resultOrder = orderService.submit(userId, orderVo.clone(OrderDTO.class));
            return R.ok().put("data", resultOrder.orElse(null));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.error("创建订单失败");
    }

    /**
     * 修改
     */
    @PutMapping("/update")
    @ApiOperation("更新指定id订单表信息")
    //@RequiresPermissions("order:order:update")
    public R update(@RequestBody OrderEntity order){
		orderService.updateById(order);

        return R.ok();
    }

    /**
     * 删除
     */
    @DeleteMapping("/delete")
    @ApiOperation("删除指定id订单表信息")
    //@RequiresPermissions("order:order:delete")
    public R delete(@RequestBody Integer[] ids){
		orderService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

    /**
     * 计算订单价格
     *
     * @param orderVO 用户id和购物车ID
     * @return
     */
    @PostMapping("/price")
    public R  calculateOrderPrice(@LoginUser Integer userId, @RequestBody OrderVO orderVO) throws Exception {
//        userId=4;
        Optional<OrderDTO> resultOrder = orderService.calculateOrderPrice(orderVO.clone(OrderDTO.class),userId);
        log.info("=====订单接口完成订单总价计算：{}",resultOrder.get());
        return R.ok().put("order",resultOrder.get());
    }

    /**
     * 计算优惠券抵扣的金额
     *
     * @param vo  优惠券Id和用户优惠券ID
     * @return
     */
    @PostMapping("/coupon")
    public R calculateCouponDiscountPrice(
            @RequestBody CalculateCouponeDiscountPriceVO vo) throws Exception{
        Optional<BigDecimal> couponDiscountPrice =
                orderService.calculateCouponDiscountPrice(vo.clone(OrderVO.class), vo.clone(CouponVO.class));
        if(!couponDiscountPrice.isPresent()){
            return R.error("calculator  coupon  is failed .....");
        }
        return R.ok().put("couponAmount",couponDiscountPrice.get());
    }

    /**
     * 计算团购优惠的金额
     *
     * @param vo  优惠券Id和用户优惠券ID
     * @return
     */
    @GetMapping("/groupon")
    public R calculateGrouponDiscountPrice(
            @RequestBody CalculateGrouponDiscountPriceVO vo) throws Exception{
        Optional<BigDecimal> grouponDiscountPrice =
                orderService.calculateGroupOnDiscountPrice(vo.clone(GrouponRulesDTO.class, CloneDirection.FORWARD));
        log.info("=====groupon  controller calculator result is :{}",grouponDiscountPrice.get());
        return R.ok().put("grouponDiscountPrice",grouponDiscountPrice.orElse(new BigDecimal("0.0")));
    }


    /**
     * 付款订单的预支付会话标识
     *
     * @param userId 用户ID
     * @param body   订单信息，{ orderId：xxx }
     * @return 支付订单ID
     */
    @PostMapping("/prepay")
    public Object prepay(@LoginUser Integer userId, @RequestBody String body, HttpServletRequest request) {
        return wxOrderService.prepay(userId, body, request);
    }


    /**
     * 微信付款成功或失败回调接口
     * <p>
     *  TODO
     *  注意，这里pay-notify是示例地址，建议开发者应该设立一个隐蔽的回调地址
     *
     * @param request 请求内容
     * @param response 响应内容
     * @return 操作结果
     */
    @PostMapping("pay-notify")
    public Object payNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return wxOrderService.payNotify(request, response);
    }
}
